package com.example.ncov_management_system.service;

import com.example.ncov_management_system.dao.MessageDao;
import com.example.ncov_management_system.entity.Message;
import com.example.ncov_management_system.entity.Student;
import com.example.ncov_management_system.entity.Teacher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

@Service
@Slf4j
public class MessageService {
    @Autowired
    private MessageDao messageDao;

    public void add(Student student, Teacher teacher) {
        Message message = new Message();
        message.setContent("你的辅导员提醒你今日该上报啦！");
        message.setCreateTime(LocalDateTime.now());
        message.setStudent(student);
        message.setTeacher(teacher);
        message.setReaded(false);
        messageDao.save(message);
    }
    public boolean isRemind(long student_id) {
        long count = messageDao.count(new Specification<Message>() {
            @Override
            public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<LocalDateTime> createTime = root.get("createTime");
                Path<Student> student = root.get("student");
                Path<Long> id = student.get("id");
                Predicate pId = criteriaBuilder.equal(id, student_id);
                Predicate greaterThanOrEqualTo = criteriaBuilder.greaterThanOrEqualTo(createTime, LocalDateTime.of(LocalDate.now(), LocalTime.of(0, 0)));
                Predicate lessThan = criteriaBuilder.lessThan(createTime, LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.of(0, 0)));
                return criteriaBuilder.and(pId, greaterThanOrEqualTo, lessThan);
            }
        });
        return count>=1;
    }

    public List<Message> findUnReadByStudentId(long studentId) {
        return messageDao.findAll(new Specification<Message>() {
            @Override
            public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Student> student = root.get("student");
                Path<Boolean> isReaded = root.get("isReaded");
                Path<Long> id = student.get("id");
                Predicate pId = criteriaBuilder.equal(id, studentId);
                Predicate pBool = criteriaBuilder.equal(isReaded, false);
                return criteriaBuilder.and(pId, pBool);
            }
        });
    }

    @Transactional
    public void readed(long id) {
        Message message = messageDao.findById(id).get();
        message.setReaded(true);
    }
    public Page<Message> list(int pn,long studentId) {
        return messageDao.findAll(new Specification<Message>() {
            @Override
            public Predicate toPredicate(Root<Message> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Student> student = root.get("student");
                Path<Long> id = student.get("id");
                return criteriaBuilder.equal(id,studentId);
            }
        }, PageRequest.of(pn, 10, Sort.by(Sort.Direction.DESC,"id")));
    }
}
